package it.tukano.swingdeco.controls;

import it.tukano.check.Todo;
import it.tukano.swingdeco.ExtUtilities;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JCheckBox;

/**
 * A JCheckBox extension
 * @author pgi
 */
public class JCheckBoxExt extends JCheckBox {

    private static final long serialVersionUID = 0;

    private Object userData;

    /**
     * Instance initializer
     */
    public JCheckBoxExt() {
    }
    
    public JCheckBoxExt setSelected() {
        setSelected(true);
        return this;
    }

    /**
     * Instance initializer
     * @param label the label of the check box
     */
    public JCheckBoxExt(String label) {
        super(label);
    }

    /**
     * Changes the selected status of this box
     * @param newState the new status
     * @return true if the state has changed, false if the selected state of
     * this box already was newState
     */
    public boolean changeSelectionStatus(boolean newState) {
        if(isSelected() != newState) {
            setSelected(newState);
            return true;
        } else {
            return false;
        }
    }

    public JCheckBoxExt onChange(Runnable task) {
        return onActionPerformed(task);
    }

    /**
     * Binds a task to the action of this control
     * @param task the task to run
     * @return this
     */
    public JCheckBoxExt onActionPerformed(Runnable task) {
        ExtUtilities.onActionPerformed(this, task);
        return this;
    }

    /**
     * Assign some user data to this component
     * @param data the data to assign
     * @return this
     */
    public JCheckBoxExt setUserData(Object data) {
        this.userData = data;
        return this;
    }

    /**
     * Access to the user data
     * @param <T> the request type of the data to get
     * @param type the class type of the data to get
     * @return the requested data or null if no data exists or if it is not of the requested type ( assignment compatible )
     */
    public <T> T getUserData(Class<T> type) {
        if(userData != null && type.isAssignableFrom(userData.getClass())) return type.cast(userData);
        return null;
    }

    /**
     * Add an action listener to this box
     * @param listener the action listener to add
     * @return this
     */
    public JCheckBoxExt onActionPerformed(ActionListener listener) {
        addActionListener(listener);
        return this;
    }

    /**
     * Sets the tooltip text for this component
     * @param bundleName the name of the resource bundle to use
     * @param tipKey the key of the resource to use for the tip
     * @return this
     */
    public JCheckBoxExt tip(String bundleName, String tipKey) {
        ExtUtilities.setToolTipText(this, bundleName, tipKey);
        return this;
    }

    public JCheckBoxExt setEditedValue(boolean value, boolean fireEvent) {
        setSelected(value);
        return this;
    }

    public JCheckBoxExt addListener(final Runnable listener) {
        addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                listener.run();
            }
        });
        return this;
    }

    public void setSelected(boolean attenuate, boolean fireEvent) {
        Todo.implementThis();
        setSelected(attenuate);
    }

    public Boolean getEditedValue() {
        return isSelected();
    }

    public JCheckBoxExt noFocus() {
        setFocusable(false);
        return this;
    }
}
